home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’95 / TrashHack / SizeTrashCan.c < prev    next >
Text File  |  1995-06-24  |  4KB  |  187 lines

  1.  
  2. #include    <Files.h>
  3. #include    <Folders.h>
  4. #include    <Memory.h>
  5. #include    <TextUtils.h>
  6.  
  7. #define        kMaxVolsChecked        10
  8.  
  9. static void SizeTrashCan (StringPtr sizeString);
  10. static long SizeDirectory (short vRefNum, long dirID);
  11.  
  12. pascal void
  13. TrashHack (StringPtr sizeString)
  14. {
  15.     if (EqualString (sizeString, "\pTrash", false, false))
  16.     {
  17.         SizeTrashCan (sizeString);
  18.     }
  19. }
  20.  
  21. void
  22. SizeTrashCan (StringPtr sizeString)
  23. {
  24.     short            vRefNum;
  25.     short            trashVRefNum;
  26.     short            i;
  27.     long            trashDirID;
  28.     long            trashSize;
  29.     Str31            buffer;
  30.     HVolumeParam    vpb;
  31.  
  32.     // initialise the trash size
  33.     trashSize = 0;
  34.     
  35.     // initialise (ignored) volume name
  36.     buffer [0] = 0;
  37.     
  38.     // for each mounted volume
  39.     for (i = 0; i < kMaxVolsChecked; i++)
  40.     {
  41.         // get vRefNum of nth mounted volume
  42.         vpb.ioCompletion = nil;
  43.         vpb.ioVolIndex = i + 1;
  44.         vpb.ioNamePtr = buffer;
  45.         
  46.         // get vol info
  47.         if (PBHGetVInfo ((HParmBlkPtr) &vpb, false) == noErr)
  48.         {
  49.             // check volume is online
  50.             if (vpb.ioVDRefNum < 0)
  51.             {
  52.                 // extract volume refnum
  53.                 vRefNum = vpb.ioVRefNum;
  54.                 
  55.                 // find the trashcan
  56.                 if (FindFolder (vRefNum, kTrashFolderType, kDontCreateFolder,
  57.                     &trashVRefNum, &trashDirID) == noErr)
  58.                 {
  59.                     // we have a trash can!
  60.                     
  61.                     // increment the total
  62.                     trashSize += SizeDirectory (trashVRefNum, trashDirID);
  63.                 }
  64.                 else
  65.                 {
  66.                     // can't FindFolder on trashcan
  67.                 }
  68.             }
  69.             else
  70.             {
  71.                 // volume is offline
  72.             }
  73.         }
  74.         else
  75.         {
  76.             // can't PBHGetVInfo
  77.         }
  78.     }
  79.     
  80.     if (trashSize)
  81.     {
  82.         // over a megabyte?
  83.         if (trashSize > (1024L * 1024L))
  84.         {
  85.             // give size in megabytes
  86.             NumToString (trashSize / (1024L * 1024L), buffer);
  87.             buffer [++buffer [0]] = 'M';
  88.         }
  89.         else
  90.         {
  91.             // give size in kilobytes
  92.             NumToString (trashSize / 1024L, buffer);
  93.             buffer [++buffer [0]] = 'K';
  94.         }
  95.         
  96.         // check length is •exactly• right
  97.         if (buffer [0] <= 5)
  98.         {
  99.             while (buffer [0] < 5)
  100.             {
  101.                 buffer [++buffer [0]] = ' ';
  102.             }
  103.             
  104.             BlockMoveData (buffer, sizeString, 6);
  105.         }
  106.     }
  107.     else
  108.     {
  109.         // otherwise the string is a misleading “0K”
  110.         BlockMoveData ("\pzeroK", sizeString, 6);
  111.     }
  112. }
  113.  
  114. // returns the combined size of the entries within the specified directory
  115. // calls itself if it finds a directory beneath the specified directory
  116. // “topLevel” parameter specifies whether this is the first iteration
  117. // used as a check to see whether the trashcan has been modified since last call
  118. static long
  119. SizeDirectory (short vRefNum, long dirID)
  120. {
  121.     OSErr            errCode;
  122.     CInfoPBRec        pb;
  123.     Str31            nameBuffer;
  124.     long            totalSize = 0;
  125.     unsigned short    numItems;
  126.     unsigned short    i;
  127.     
  128.     // make up a GetCatInfo paramblock
  129.     // to get info on the directory whose ID we are passed
  130.     pb.dirInfo.ioCompletion = nil;
  131.     pb.dirInfo.ioNamePtr = nameBuffer;
  132.     pb.dirInfo.ioVRefNum = vRefNum;
  133.     pb.dirInfo.ioFDirIndex = -1;
  134.     pb.dirInfo.ioDrDirID = dirID;
  135.     
  136.     // get cat info!
  137.     errCode = PBGetCatInfo (&pb, false);
  138.     
  139.     // check error code
  140.     if (errCode != noErr)
  141.     {
  142.         // oops - can't get info for this directory - return zero size
  143.         return 0;
  144.     }
  145.  
  146.     // find out how many entries we have in the directory
  147.     numItems = pb.dirInfo.ioDrNmFls;
  148.     
  149.     // loop thru each - the index starts at 1, remember
  150.     for (i = 1; i <= numItems; i++)
  151.     {
  152.         // configure the paramblock appropriately
  153.         // note have to reinitialise the dirID field every time
  154.         pb.dirInfo.ioFDirIndex = i;
  155.         pb.dirInfo.ioDrDirID = dirID;
  156.         
  157.         // get the stuff about the file/dir
  158.         errCode = PBGetCatInfo (&pb, false);
  159.         
  160.         // check error code
  161.         if (errCode != noErr)
  162.         {
  163.             // oops - can't get info on this entry
  164.             // leave well alone
  165.             continue;
  166.         }
  167.         
  168.         // if it's a directory
  169.         if (pb.dirInfo.ioFlAttrib & ioDirMask)
  170.         {
  171.             // SUBDIRECTORY
  172.             
  173.             // call myself to find its size and add that to the total
  174.             totalSize += SizeDirectory (vRefNum, pb.dirInfo.ioDrDirID);
  175.         }
  176.         else
  177.         {
  178.             // FILE
  179.             
  180.             // take the •physical• sizes of the data and resource forks
  181.             totalSize += pb.hFileInfo.ioFlPyLen + pb.hFileInfo.ioFlRPyLen;
  182.         }
  183.     }
  184.     
  185.     return totalSize;
  186. }
  187.